package org.example.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.example.domain.*;

import org.example.enums.ContractTypeEnum;
import org.example.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@RequestMapping("factoring")
@RestController
public class JrFactoringcontroller {
    @Autowired
    TCfContractService tCfContractService;//租房合同
    @Autowired
    TCwReceiptPlanService receiptPlanService;//收款计划
    @Autowired
    TJrProductService productService;
    @Autowired
    TFkBusinessCreditService tFkBusinessCreditService;//风控公寓授信主表

    @Autowired
    TFkBusinessCreditSubService tFkBusinessCreditSubService;//风控公寓授信子表


    @Autowired
    TJrFactoringService factoringService;//租约保理申请表

    /**
     * 查询租房合同 分页
     * 小区名称、租客姓名查询
     * @return
     * @throws ParseException
     */
    @GetMapping("searchCfContract")
    public AjaxResult searchCfContract(Page page,TCfContract contract){
        return AjaxResult.success(tCfContractService.selectPageVo(page,contract));
    }
    /**
     * 根据合同和保理产品计算该合同的保理申请明细
     * @param contractId 申请保理的租房合同ID
     * @param productId 所选的保理产品ID
     * @param interestRate 年利率
     * @param serviceFee 服务费率
     * @param rowNo 行号
     * @return
     */
    @GetMapping("catulateFactorInfo")
    public AjaxResult catulateFactorInfo(Integer contractId, Integer productId, Float interestRate, Float serviceFee, Integer rowNo){
        TCfContract one = tCfContractService.getById(contractId);//获取对象
        one.setContractId(contractId);//为返回前端赋值申请保理的租房合同ID
    // 查询剩余租约期限（未付款的房租账期） 剩余租约金房租合计
        HashMap<String, Object> map = new HashMap<>();
        map.put("contractId",contractId);//合同id
        map.put("contractType", ContractTypeEnum.CF.getIndex());//合同类型 1，收房 2.出房

        List<TCwReceiptPlan> list = receiptPlanService.getList(map);

        if (list != null && list.size() > 0) {
            // 借款账期开始日拿第一条的开始日期
            one.setBorrowedStart(list.get(0).getPaymentDaysBegin());
            // 借款账期结束日拿最后一条的结束日期
            one.setBorrowedEnd(list.get(list.size() - 1).getPaymentDaysEnd());

            // 应收租约金额：即剩余租约金房租合计
            //循环添加所有的余租约金房租合计
            BigDecimal shouldMonthRent = BigDecimal.ZERO;
            for (TCwReceiptPlan one2 : list) {
                shouldMonthRent = shouldMonthRent.add(one2.getPaymentAmount());
            }
            //为赋值
            one.setShouldMonthRent(shouldMonthRent);


            // 借款周期(多少个月 = 付几 * 剩余未付房租账期数)
            one.setFactoringPeriod(one.getPaymentType() * list.size());
            //根据前端穿过来的productId获取金融分期类型
            TJrProduct productEntity = productService.getById(productId);
            //使用获取出来的金融分期列表对象.get授信额度转换成为BigDecimal，因为在进行数学运算时，使用 BigDecimal 能够避免精度
            BigDecimal bigDecimal = new BigDecimal(String.valueOf(productEntity.getCreditLine()));
            //它表示产品授信额度除以 100 后得到的比例（保留两位小数）。这样做是因为通常情况下授信额度是以百分数形式表示的，但在实际计算中需要将其转换为小数
            //(单位：%，比如80%，存的是80)所以要除以100保留两位小数并四舍五入
            //setScale(2, BigDecimal.ROUND_HALF_UP)对结果再次结算四舍五入
            BigDecimal scale = bigDecimal.divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP).setScale(2, RoundingMode.HALF_UP);


            one.setFactoringCreditMoney(scale);//借款周期


            //one.getFactoringCreditMoney()获取保理授信总金额；
            //new BigDecimal(interestRate/(100 * 12))将输入的年利率除以100转换成小数，并除以12转换成月利率
            //利息 = 保理授信总金额 *月利率 *月数  = 保理授信总金额 * 年利率/12 *月数 (备注：四舍五入)
            BigDecimal multiply = one.getFactoringCreditMoney().multiply(new BigDecimal(interestRate / 100 / 12));
            BigDecimal decimal = multiply.multiply(new BigDecimal(one.getFactoringPeriod())).setScale(2, BigDecimal.ROUND_HALF_UP);


            one.setFactoringInterest(decimal);//为利息赋值

            // 服务费 = 保理授信金额*服务费率/12*月数(备注：四舍五入)
            one.setServiceFee(one.getFactoringCreditMoney().multiply(new BigDecimal(serviceFee/(100 * 12)))
                    .multiply(new BigDecimal(one.getFactoringPeriod())).setScale(2, BigDecimal.ROUND_HALF_UP));



            if (null != productEntity.getInstalmentPeriod() && -1L != productEntity.getInstalmentPeriod() // 不是无限期
                    // 借款周期不能超过产品设定的分期期限
                    && one.getFactoringPeriod() > productEntity.getInstalmentPeriod()) {
                // 租约期限超过保理产品期限
                return AjaxResult.error("租约期限超过保理产品期限");
            } else {
                ArrayList<TCfContract> list1 = new ArrayList<>();
                list1.add(one);
                return AjaxResult.success(list1);
            }
        }else {
            return AjaxResult.error("该合同剩余未逾期房租租约金额为0，不可申请租约保理！");
        }
    }



    @PostMapping("saveFactoringApply")
    public AjaxResult saveFactoringApply(@RequestBody TJrFactoring tJrFactoring) {
        //根据商户ID查询风控公寓授信主表
        QueryWrapper<TFkBusinessCredit> wrapper = new QueryWrapper<>();
        wrapper.eq("business_id",tJrFactoring.getBusinessId());
        TFkBusinessCredit objectBusiness = tFkBusinessCreditService.getOne(wrapper);

        TFkBusinessCreditSub findById = tFkBusinessCreditSubService.findByBusinessAndProductId(tJrFactoring.getBusinessId(),tJrFactoring.getJrProductId());

        if(findById == null) {
            return AjaxResult.error("授信额度不足，请联系维数公寓客服：400-008-3363");
        }

        BigDecimal subtractProduct = BigDecimal.ZERO;
        //商户该产品总授信额度减该产品已用授信额度
        //判断用户的已用授信额度不等于空
        //那么就将其从总授信额度中减去，得到产品的授信额度剩余值否则，直接使用总授信额度作为产品的授信额度剩余值
        if(findById.getUsedCreditline() != null && !findById.getUsedCreditline().equals(BigDecimal.ZERO)) {
            subtractProduct = findById.getTotalCreditline().subtract(findById.getUsedCreditline());
        } else {
            subtractProduct = findById.getTotalCreditline();
        }

        //申请分期金额大于该商户中的该产品剩余授信金额
        //compareTo比较大小的
        // 如果当前对象小于另一个对象，则返回一个负整数。
        //如果当前对象等于另一个对象，则返回0。
        //如果当前对象大于另一个对象，则返回一个正整数。
        if(tJrFactoring.getRentMoney().compareTo(subtractProduct) == 1) {
            return AjaxResult.error("授信额度不足，请联系维数公寓客服：400-008-3363");
        }

        //检查商户的月度总授信额度是否存在且不为零，如果是，则将其用于计算可用月度授信额度  风控公寓授信子表
        if(findById.getMonthlyTotalCreditline() != null && !findById.getMonthlyTotalCreditline().equals(BigDecimal.ZERO)) {
            //商户总授信额度减已用授信额度
            BigDecimal subtractMonthly = BigDecimal.ZERO;
            if(findById.getMonthlyUsedCreditline() != null && !findById.getMonthlyUsedCreditline().equals(BigDecimal.ZERO)) {
                //可用月度授信额度 = 月度总授信额度 - 月度已使用授信额度
                subtractMonthly = findById.getMonthlyTotalCreditline().subtract(findById.getMonthlyUsedCreditline());
            } else {//否则
                //可用月度授信额度等于商户的月度总授信额度
                subtractMonthly = findById.getMonthlyTotalCreditline();
            }
            if(tJrFactoring.getRentMoney().compareTo(subtractMonthly) == 1) {
                return AjaxResult.error("授信额度不足，请联系维数公寓客服：400-008-3363");
            }
            }


        else {
            //判断风控公寓授信主表中的维数月授信额度不为空
            if(objectBusiness.getHlMonthlyTotalCreditline() != null && !objectBusiness.getHlMonthlyTotalCreditline().equals(BigDecimal.ZERO)) {
                //商户月授信额度减月已用授信额度
                BigDecimal subtractMonthly = BigDecimal.ZERO;
                // 判断风控公寓授信主表中的维数月授信额度不为空
                if(objectBusiness.getHlMonthlyUsedCreditline() != null && !objectBusiness.getHlMonthlyUsedCreditline().equals(BigDecimal.ZERO)) {
                    //可用月度授信额度 = 月度总授信额度 - 月度已使用授信额度
                    subtractMonthly = objectBusiness.getHlMonthlyTotalCreditline().subtract(objectBusiness.getHlMonthlyUsedCreditline());
                } else {//否则
                    //可用月度授信额度等于商户的月度总授信额度
                    subtractMonthly = objectBusiness.getHlMonthlyTotalCreditline();
                }
                //申请分期金额大于该商户月剩余授信金额
                if(tJrFactoring.getRentMoney().compareTo(subtractMonthly) == 1) {
                    return AjaxResult.error("授信额度不足，请联系维数公寓客服：400-008-3363");
                }
            }
        }
        //风控公寓授信主表 中的维数已用授信额度不为空
        BigDecimal hlUsedCreditline = BigDecimal.ZERO;

        if(objectBusiness.getHlUsedCreditline() != null && !objectBusiness.getHlUsedCreditline().equals(BigDecimal.ZERO)) {
            //风控公寓授信主表维数已用授信额度 + 租约保理申请表中应收租约合计
            hlUsedCreditline = objectBusiness.getHlUsedCreditline().add(tJrFactoring.getRentMoney());
        } else {
            hlUsedCreditline = tJrFactoring.getRentMoney();
        }
        //重新为风控公寓授信主表中维数已用授信额度赋值
        objectBusiness.setHlUsedCreditline(hlUsedCreditline);

            //风控公寓授信主表维数月授信额度不为空
        if(objectBusiness.getHlMonthlyTotalCreditline() != null && !objectBusiness.getHlMonthlyTotalCreditline().equals(BigDecimal.ZERO)) {
            BigDecimal hlMonthlyUsedCreditline = BigDecimal.ZERO;
            //风控公寓授信主表维数月已用授信额度不为空
            if(objectBusiness.getHlMonthlyUsedCreditline() != null && !objectBusiness.getHlMonthlyUsedCreditline().equals(BigDecimal.ZERO)) {
                //风控公寓授信主表维数月已用授信额度 + 租约保理申请表应收租约合计
                hlMonthlyUsedCreditline = objectBusiness.getHlMonthlyUsedCreditline().add(tJrFactoring.getRentMoney());
            } else {
                // 租约保理申请表应收租约合计
                hlMonthlyUsedCreditline = tJrFactoring.getRentMoney();
            }
            //维数月已用授信额度赋值
            objectBusiness.setHlMonthlyUsedCreditline(hlMonthlyUsedCreditline);
        }
        //修改时间
        //修改人
        objectBusiness.setUpdateTime(new Date());
        objectBusiness.setUpdateUserid(SecurityUtils.getUserId());
        tFkBusinessCreditService.saveOrUpdate(objectBusiness);

        BigDecimal usedCreditlineProduct = BigDecimal.ZERO;
        //判断维数公寓授信子表中的月度授信额度不为空
        if(findById.getMonthlyTotalCreditline() != null && !findById.getMonthlyTotalCreditline().equals(BigDecimal.ZERO)) {
            BigDecimal hlMonthlyUsedCreditline = BigDecimal.ZERO;
            //判断维数公寓授信子表中的月度已用授信额度不为空
            if(findById.getMonthlyUsedCreditline() != null && !findById.getMonthlyUsedCreditline().equals(BigDecimal.ZERO)) {
                //为空则月度已用授信额度 = 月度已用授信额度 + 应收租约合计
                hlMonthlyUsedCreditline = findById.getMonthlyUsedCreditline().add(tJrFactoring.getRentMoney());
            } else {
                //不为空则 月度已用授信额度 =  应收租约合计
                hlMonthlyUsedCreditline = tJrFactoring.getRentMoney();
            }
            //为月度已用授信额度 赋值
            findById.setMonthlyUsedCreditline(hlMonthlyUsedCreditline);
        }

        findById.setUpdateUserid(SecurityUtils.getUserId());
        tFkBusinessCreditSubService.saveOrUpdate(findById);

        factoringService.addTJrFactoring(tJrFactoring);
        return AjaxResult.success();
    }
}
